const RoomMember = require('../models/RoomMember');
const Room = require('../models/Room');
const Message = require('../models/Message');
const Apply = require('../models/Apply');
const MemberFriend = require('../models/MemberFriend');
const Member = require('../models/Member');

// 用户好有列表
async function memberFriends(memberId) {
    let friends = await MemberFriend
        .select('member_friend.id as chatId', 'member.id', 'username', 'avatar', 'gender', 'member.createdAt')
        .where('memberId', memberId)
        .orWhere('friendId', memberId)
        .join('member', `(member.id = memberId or member.id = friendId) and member.id != ${memberId}`)
        .execute();
    if(!friends) {
        return friends;
    }
    let messages = await Message
        .select('message.id', 'messageTypeId', 'receiverId', 'chatId', 'content', 'message.status', 'message.createdAt', 'senderId', 'username', 'avatar', 'gender', 'member.createdAt as registerAt')
        .join('member', 'member.id = senderId')
        .whereIn('chatId', friends.map((friend) => friend.chatId))
        .where('chatTypeId', 'person')
        .orderBy('message.createdAt asc')
        .execute();
    const friendMessages = {};
    messages.map((message) => {
        if(typeof friendMessages?.[message.chatId] === 'undefined') {
            friendMessages[message.chatId] = [];
        }
        friendMessages[message.chatId].push({
            id: message.id,
            typeId: message.typeId,
            messageTypeId: message.messageTypeId,
            content: message.content,
            status: message.status,
            createdAt: message.createdAt,
            member: {
                id: message.senderId,
                username: message.username,
                avatar: message.avatar,
                gender: message.gender,
                createdAt: message.registerAt,
            },
        });
    });

    friends = friends.map((friend) => {
        return {...friend, messages: friendMessages?.[friend.chatId]}
    });
    return friends;
}

// 用户群聊列表
async function memberRooms(memberId) {
    let rooms = await Room
        .select('distinct room.id', 'name', 'typeId', 'room.status', 'room.createdAt')
        .join('room_member', 'room.id = roomId')
        .where('memberId', memberId)
        .execute();
    if(!rooms) {
        return rooms;
    }
    let members = await RoomMember
        .select('roomId', 'username', 'avatar', 'gender', 'member.createdAt')
        .whereIn('roomId', rooms.map((room) => room.id))
        .join('member', 'member.id = memberId')
        .execute();
    let messages = await Message
        .select('message.id', 'messageTypeId', 'receiverId', 'chatId', 'content', 'message.status', 'message.createdAt', 'senderId', 'username', 'avatar', 'gender', 'member.createdAt as registerAt')
        .join('member', 'member.id = senderId')
        .whereIn('chatId', rooms.map((room) => room.id))
        .where('chatTypeId', 'room')
        .orderBy('message.createdAt asc')
        .execute();

    const roomMembers = {};
    members.map((member) => {
        if(typeof roomMembers?.[member.roomId] === 'undefined') {
            roomMembers[member.roomId] = [];
        }
        roomMembers[member.roomId].push(member);
    });
    const roomMessages = {};
    messages.map((message) => {
        if(typeof roomMessages?.[message.chatId] === 'undefined') {
            roomMessages[message.chatId] = [];
        }
        roomMessages[message.chatId].push({
            id: message.id,
            typeId: message.typeId,
            messageTypeId: message.messageTypeId,
            content: message.content,
            status: message.status,
            createdAt: message.createdAt,
            member: {
                id: message.senderId,
                username: message.username,
                avatar: message.avatar,
                gender: message.gender,
                createdAt: message.registerAt,
            },
        });
    });

    rooms = rooms.map((room) => {
        return {...room, members: roomMembers?.[room.id] || [], messages: roomMessages?.[room.id]}
    });
    return rooms;
}

// 好友/入群申请记录
async function memberFriendApplies(memberId) {
    let applies = await Apply
        .select('apply.id', 'chatTypeId', 'receiverId', 'senderId', 'remark', 'chatId', 'apply.status', 'apply.createdAt', 'sender.username as sendername', 'receiver.username as receivername', 'sender.avatar', 'sender.gender', 'sender.createdAt as registerAt')
        .join('member as sender', 'sender.id = senderId')
        .join('member as receiver', 'receiver.id = receiverId')
        .where('receiverId', memberId)
        .where('applyTypeId', 'friend')
        .orderBy('apply.createdAt asc')
        .execute();

    applies = (applies || []).map(({sendername, receivername, avatar, gender, registerAt, ...apply}) => {
        return {
            ...apply,
            sender: {
                id: apply.senderId,
                username: sendername,
                avatar,
                gender,
                createdAt: registerAt,
            },
            receiver: {
                id: apply.receiverId,
                username: receivername,
            },
        }
    });
    return applies;
}

// 通过好有请求
async function memberAcceipt(id, member) {
    const apply = await Apply.findOne(id);
    if(!apply) {
        return null;
    }
    apply.status = 10;
    // console.log('apply', apply);
    const {token, password, ...sender} = await Member.findOne(apply.senderId);
    Apply.where('id', id).update({status: apply.status});
    if(apply.chatTypeId === 'person') {
        const friend = await MemberFriend
            .select('member_friend.id')
            .where([['memberId', apply.senderId], ['friendId', member.id]])
            .orWhere([['memberId', member.id], ['friendId', apply.senderId]])
            .first();

        // console.log('accept friend', friend);
        if(friend) {
            return {...apply, friend: {...sender, chatId: friend.id}};
        }
        const chatId = await MemberFriend.insert({memberId: member.id, friendId: apply.senderId, status: 1});

        return {...apply, friend: {...sender, chatId}}

    }
    if(apply.chatTypeId === 'room') {
        const member = await RoomMember
            .select('id')
            .where('room_id', apply.chatId)
            .where('memberId', apply.senderId)
            .first();

        // console.log('accept member', member);
        if(member) {
            return {...apply, member: sender};
        }
        const chatId = await RoomMember.insert({roomId: apply.chatId, memberId: apply.senderId, status: 1});

        return {...apply, member: {...sender, chatId}};
    }
    return null;
}

async function memberSearch(keyword, self) {
    const members = await Member.select('id', 'username', 'avatar', 'gender', 'createdAt')
        .where('username', 'like', `%${keyword}%`)
        .where('id', '!=', self)
        .limit(20).execute();

    return members;
}

module.exports = {
    memberFriends,
    memberRooms,
    memberFriendApplies,
    memberAcceipt,
    memberSearch,
};